﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using YJKPatternSign.StairsClearHeightDimension;
using YJKPatternSign.StairsRoomPlanSign.ControlLayer;

namespace YJKPatternSign.StairsRoomPlanSign.ModelLayer
{
	public abstract class BaseShapePacker
	{
		public List<Curve> LstAllShapeCurve
		{
			get
			{
				return this.m_lstAllShapeCurve;
			}
			protected set
			{
				this.m_lstAllShapeCurve = value;
			}
		}

		public List<XYZ> LstAllMidPoint
		{
			get
			{
				return this.m_lstAllMidPoint;
			}
			protected set
			{
				this.m_lstAllMidPoint = value;
			}
		}

		public XYZ MidPoint
		{
			get
			{
				return this.m_midPoint;
			}
			protected set
			{
				this.m_midPoint = value;
			}
		}

		public Element ThisElement
		{
			get
			{
				return this.m_thisElement;
			}
			protected set
			{
				this.m_thisElement = value;
			}
		}

		public ShapeViewKindEnum ViewKind
		{
			get
			{
				return this.viewKind;
			}
			protected set
			{
				this.viewKind = value;
			}
		}

		public List<Curve> LstAllCutedCurve
		{
			get
			{
				return this.m_lstAllCutedCurve;
			}
			protected set
			{
				this.m_lstAllCutedCurve = value;
			}
		}

		public List<Curve> LstAddedCurves
		{
			get
			{
				return this.m_lstAddedCurves;
			}
			protected set
			{
				this.m_lstAddedCurves = value;
			}
		}

		public BaseShapePacker(Element inputElement, List<Curve> inputLstCurve)
		{
			this.ThisElement = inputElement;
			this.LstAllShapeCurve = Utility.ChangeLstCurveZ(inputLstCurve, SignManger.ThisStairPlandDataPacker.NowViewZ);
			foreach (Curve curve in this.LstAllShapeCurve)
			{
				this.LstAllMidPoint.Add(curve.Evaluate(0.5, true));
			}
			this.LstAllCutedCurve.AddRange(this.LstAllShapeCurve);
			this.MidPoint = StairsClearHeightDimensionGeometry.CalculatMidPoint(this.LstAllMidPoint);
		}

		public virtual void UpdataThisShapeByView(ViewData inputData)
		{
		}

		public virtual bool IfShapeNearThis(BaseShapePacker input)
		{
			bool result = false;
			List<Curve> lstAllShapeCurve = input.LstAllShapeCurve;
			IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
			foreach (Curve curve in this.LstAllShapeCurve)
			{
				foreach (Curve curve2 in lstAllShapeCurve)
				{
					SetComparisonResult setComparisonResult = curve.Intersect(curve2, out intersectionResultArray);
					if (setComparisonResult == SetComparisonResult.Overlap || setComparisonResult == SetComparisonResult.Subset || setComparisonResult == SetComparisonResult.Equal)
					{
						result = true;
					}
				}
			}
			return result;
		}

		public virtual bool TryGetDimensionInformensionByLine(Line inputLine, out DimensionInformensionBean dimensionBean, bool ifUseCutedShape = false, bool ifUseAddedCurve = false, bool ifUseUnBound = false)
		{
			Line line = inputLine.Clone() as Line;
			line.MakeUnbound();
			List<Curve> list = new List<Curve>();
			if (ifUseCutedShape)
			{
				using (List<Curve>.Enumerator enumerator = this.LstAllCutedCurve.GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						Curve curve = enumerator.Current;
						list.Add(curve.Clone());
					}
					goto IL_97;
				}
			}
			foreach (Curve curve2 in this.LstAllShapeCurve)
			{
				list.Add(curve2.Clone());
			}
			IL_97:
			if (ifUseAddedCurve)
			{
				this.AddAppendCurves(ref list);
			}
			if (ifUseUnBound)
			{
				foreach (Curve curve3 in list)
				{
					curve3.MakeUnbound();
				}
			}
			List<XYZ> list2 = new List<XYZ>();
			IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
			using (List<Curve>.Enumerator enumerator = list.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
                    if ((int)enumerator.Current.Intersect(line, out intersectionResultArray) == 8)
					{
						for (int i = 0; i < intersectionResultArray.Size; i++)
						{
							list2.Add(intersectionResultArray.get_Item(i).XYZPoint);
						}
					}
				}
			}
			if (list2.Count >= 2)
			{
				dimensionBean = new DimensionInformensionBean(inputLine, list2, null);
				return true;
			}
			dimensionBean = null;
			return false;
		}

		public virtual void AddAppendCurves(ref List<Curve> useCurve)
		{
			useCurve.AddRange(this.LstAddedCurves);
		}

		public virtual bool TryGetAPathInShape(XYZ startPoint, XYZ endPoint, double useZ, out List<Curve> lstPathes)
		{
			lstPathes = new List<Curve>();
			XYZ xyz = new XYZ(startPoint.X, startPoint.Y, useZ);
			XYZ xyz2 = new XYZ(endPoint.X, endPoint.Y, useZ);
			if (xyz.IsAlmostEqualTo(xyz2))
			{
				return false;
			}
			Line line = Line.CreateBound(xyz, xyz2);
			lstPathes.Add(line);
			IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
			List<XYZ> list = new List<XYZ>();
			using (List<Curve>.Enumerator enumerator = this.LstAllShapeCurve.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
                    if ((int)enumerator.Current.Intersect(line, out intersectionResultArray) == 8)
					{
						for (int i = 0; i < intersectionResultArray.Size; i++)
						{
							list.Add(intersectionResultArray.get_Item(i).XYZPoint);
						}
					}
				}
			}
			foreach (XYZ xyz3 in list)
			{
				if (!xyz3.IsAlmostEqualTo(xyz) && !xyz3.IsAlmostEqualTo(xyz2))
				{
					lstPathes = new List<Curve>();
					return false;
				}
			}
			return true;
		}

		public virtual void AddACurveToShape(Curve input)
		{
			this.LstAddedCurves.Add(input);
		}

		protected Element m_thisElement;

		protected List<Curve> m_lstAllShapeCurve = new List<Curve>();

		protected List<Curve> m_lstAllCutedCurve = new List<Curve>();

		protected List<XYZ> m_lstAllMidPoint = new List<XYZ>();

		protected XYZ m_midPoint;

		protected List<Curve> m_lstAddedCurves = new List<Curve>();

		protected ShapeViewKindEnum viewKind;
	}
}
